/****
	Copyright 2012 Taras Kulbachka

	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at

		http://www.apache.org/licenses/LICENSE-2.0

	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/
package com.atdevsoft.apps.abyss.utils;

import java.util.ArrayList;

import com.atdevsoft.apps.abyss.QuotesActivity;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.FrameLayout;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;


public class AbyssViewPager extends ViewPager {
	private Context mContext;	
	private ListsEventsCallback mCallbacks;
	private int mListResource;
	private SparseArray<CustomList> mLists;
	private int mPrevPage;	
	private int mBackgroundColor;
	
    public interface ListsEventsCallback {
        int getPagesCount();
        Cursor getThisPageCursor();
        Cursor getNextPageCursor();
        Cursor getPrevPageCursor();        
        SimpleCursorAdapter getAdapter(Cursor c);
        void onPageMovedBack();        
        void onPageMovedForward();
    }		
	
    private void setListViewColor(ListView lv, int color) {
    	lv.setCacheColorHint(color);
    	lv.setBackgroundColor(color);
    	lv.invalidate(); 
    }
    
    public void setListsBackgroundColor(int color) {
    	setBackgroundColor(color);
    	mBackgroundColor = color;
    	for (int i = 0; i < mLists.size(); i++) {
			if ((mLists.get(i) != null) && (mLists.get(i).getListView() != null)) {
				ListView lv = mLists.get(i).getListView();				
				setListViewColor(lv, color);
			}
		}    	
    }
    
    public void setInitialPage(int page) {
    	mPrevPage = page;
    	
    	
    	if (getAdapter() == null) {
    		setAdapter(new InfinitePagerAdapter());    		
    	} else {   		
    		setAdapter(getAdapter());
    	}
    	setCurrentItem(page, false);
    }
    
    private void checkListAdapter(int listIndex, int currentIndex, CustomList listView) {
    	SimpleCursorAdapter adapter = (SimpleCursorAdapter)listView.getListAdapter();
    	if ((adapter != null) && (adapter.getCursor() != null))
    		return;
    	if (mCallbacks == null)
    		return;
    	Cursor c = null;
    	if (listIndex == currentIndex)
    		c = mCallbacks.getThisPageCursor();
    	if (listIndex == currentIndex - 1)
    		c = mCallbacks.getPrevPageCursor();
    	if (listIndex == currentIndex + 1)
    		c = mCallbacks.getNextPageCursor();
    	if (c == null)
    		return;
    	
    	setupListAdapter(c, listView);
    }
    
    private void setupListAdapter(Cursor c, CustomList listView) {
    	if (c.getCount() == 0) {
    		listView.setListAdapter(null);
    		listView.notifyCursorChanged();
    		return;
    	}    		
        if (listView.getListAdapter() != null) {
        	SimpleCursorAdapter adapter = (SimpleCursorAdapter)listView.getListAdapter();        	
        	adapter.changeCursor(c);       	
        	listView.getListView().setSelectionAfterHeaderView();        	
        } else {
        	
	        try {
	        	SimpleCursorAdapter adapter = mCallbacks.getAdapter(c);	
	        	listView.setListAdapter(adapter);

	        } catch (Exception e) {
	        	e.printStackTrace();
	        } 		    	
        }    
        listView.notifyCursorChanged();
    }
    
    public ListView getCurrentListView() {
    	if (mLists.get(Integer.valueOf(getCurrentItem())) == null)
    		return null;
    	return ((CustomList)mLists.get(Integer.valueOf(getCurrentItem()))).getListView();
    }
    
    public ArrayList<ListView> getAllListViews() {
    	return null;
    }    
    
    public void scrollListView(int delta) {
    	ListView lv = getCurrentListView();
        int pos = lv.getFirstVisiblePosition();  
        if ((pos + delta > lv.getCount() - 1) || (pos + delta < 0))
            return;  
        lv.setSelection(pos + delta);  
        lv.clearFocus();  
    }     
    
	public void init(int listResource, ListsEventsCallback callbacks) {
		mCallbacks = callbacks;
		mListResource = listResource;
		
		setOnPageChangeListener(new OnPageChangeListener() {
			
			@Override
			public void onPageSelected(int arg0) {
				if (mCallbacks == null)
					return;
				if (arg0 == mPrevPage + 1)
					mCallbacks.onPageMovedForward();
				if (arg0 == mPrevPage - 1)
					mCallbacks.onPageMovedBack();
				
				if (arg0 == 0) { // first page could overlap with second causing strange artifacts, so we will clear all data when entering first page
					// loop from i = 1 to skip first page
					for (int i = 1; i < mLists.size(); i++) {
						if (mLists.get(i).getListAdapter() != null) {
							((SimpleCursorAdapter)mLists.get(i).getListAdapter()).changeCursor(null);
						}
					}
				}
				
				CustomList l = mLists.get(Integer.valueOf(arg0 - 1));
				if (l != null)
					checkListAdapter(arg0 - 1, arg0, l);
				l = mLists.get(Integer.valueOf(arg0 + 1));
				if (l != null)
					checkListAdapter(arg0 + 1, arg0, l);
				l = mLists.get(Integer.valueOf(arg0));
				if (l != null)
					checkListAdapter(arg0, arg0, l);
				
				mPrevPage = arg0;
			}
			
			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
			}
			
			@Override
			public void onPageScrollStateChanged(int state) {
				if (state == ViewPager.SCROLL_STATE_IDLE) {
					
				}
				
			}
		});		
	}
	
	public AbyssViewPager(Context context) {
		super(context);		
		mContext = context;		
		mPrevPage = 0;
		mBackgroundColor = Color.BLACK;
		mLists = new SparseArray<CustomList>();
	}

	public AbyssViewPager(Context context, AttributeSet attrs) {
		super(context, attrs);
		mContext = context;
		mPrevPage = 0;
		mBackgroundColor = Color.BLACK;
		mLists = new SparseArray<CustomList>();
	}

	private class InfinitePagerAdapter extends PagerAdapter {		
	    
		@Override
		public void destroyItem(View container, int position, Object object) {
			CustomList lst = mLists.get(Integer.valueOf(position));
			if (lst != null) {				
				((ViewPager) container).removeView(lst);
				mLists.remove(Integer.valueOf(position));
			}
		}

		@Override
		public void finishUpdate(View container) {
		}

		@Override
		public int getCount() {
			return mCallbacks.getPagesCount();
		}

		@Override
		public Object instantiateItem(View container, int position) {
			ViewPager vpContainer = (ViewPager)container;
			CustomList res = new CustomList(mContext, mListResource);			
			ListView lv = res.getListView();
			if (lv != null)
				setListViewColor(lv, mBackgroundColor);
			checkListAdapter(position, mPrevPage, res);
			mLists.put(position, res);
			vpContainer.addView(res);			
			return res;
		}
	
		
		@Override
		public boolean isViewFromObject(View view, Object object) {
			return object == view;
		}

		@Override
		public void restoreState(Parcelable state, ClassLoader loader) {
		}

		@Override
		public Parcelable saveState() {
			return null;
		}

		@Override
		public void startUpdate(View container) {
		}
	}	
	
    private class CustomList extends FrameLayout {
    	public void notifyCursorChanged() {
    		SimpleCursorAdapter adapter = (SimpleCursorAdapter)getListAdapter();
    		boolean hasRecords = (adapter != null) && (adapter.getCursor() != null) && (adapter.getCursor().getCount() > 0);
    		TextView tv = (TextView)findViewById(android.R.id.empty);
    		if (hasRecords)
    			tv.setVisibility(View.GONE);
    		else
    			tv.setVisibility(View.VISIBLE);
    	}
    	
    	public CustomList(Context context, int listResource) {
			super(context);			
			LayoutInflater li = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);			
			//TODO: add all children of inflated object and remove the rest
			this.addView(li.inflate(listResource, null, false));
			
			getListView().setOnItemClickListener(new OnItemClickListener() {

				@Override
				public void onItemClick(AdapterView<?> arg0, View arg1,
						int arg2, long arg3) {
					Intent i = new Intent(QuotesActivity.ACTION_NEED_REFRESH_DATA);
					i.putExtra(QuotesActivity.INTENT_EXTRA_REFRESH_TYPE, QuotesActivity.REFRESH_TYPE_SET_NEXT_PAGE);
					mContext.sendBroadcast(i);					
				}
			});
		}

		public ListAdapter getListAdapter() {
			ListView lv = getListView();    		
    		return lv.getAdapter();
    	}
    	
    	public void setListAdapter(ListAdapter newAdapter) {
    		ListView lv = getListView(); 
    		if (lv != null)
    			lv.setAdapter(newAdapter);
    	}
    	
    	public ListView getListView() {
    		return (ListView)findViewById(android.R.id.list);
    	}
    	
    } 	
}